package com.woniuxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.entity.AllArticle;
import com.woniuxy.entity.DTO.ArticleQueryDTO;
import com.woniuxy.mapper.ArticleMapper;
import com.woniuxy.service.IArticleService;
import com.woniuxy.util.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author pml
 * @Date 2025/7/16 10:10
 * @Description 帖子服务实现类
 * 实现帖子相关的业务逻辑，使用MyBatis-Plus提供的CRUD方法
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, AllArticle> implements IArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    /**
     * 分页多条件查询帖子列表
     * 复用用户管理模块的分页查询逻辑，但增加了帖子特有的查询条件处理
     */
    @Override
    public PageResult<AllArticle> getArticleList(ArticleQueryDTO queryDTO) {
        // 创建分页对象，设置当前页码和每页数量
        // 使用MyBatis-Plus分页插件自动计算总记录数和总页数
        Page<AllArticle> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        // 创建查询条件构造器
        // 动态构建SQL查询条件，避免编写大量if-else拼接SQL
        QueryWrapper<AllArticle> queryWrapper = new QueryWrapper<>();

        // 标题模糊查询
        if (queryDTO.getTitle() != null && !queryDTO.getTitle().isEmpty()) {
            queryWrapper.like("title", queryDTO.getTitle());
        }

        // 内容模糊查询
        // 使用like而不是eq，允许部分匹配，提高搜索灵活性
        if (queryDTO.getContent() != null && !queryDTO.getContent().isEmpty()) {
            queryWrapper.like("content", queryDTO.getContent());
        }

        // 用户ID精确查询
        if (queryDTO.getUserId() != null) {
            queryWrapper.eq("user_id", queryDTO.getUserId());
        }

        // 状态精确查询
        // 状态是枚举值，使用精确匹配确保查询准确
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }

        // 话题标签ID精确查询
        if (queryDTO.getTopicId() != null) {
            queryWrapper.eq("topic_id", queryDTO.getTopicId());
        }

        // 发布时间范围查询
        // 使用ge(大于等于)和le(小于等于)实现时间区间查询
        if (queryDTO.getCreateTimeStart() != null) {
            queryWrapper.ge("create_time", queryDTO.getCreateTimeStart());
        }
        if (queryDTO.getCreateTimeEnd() != null) {
            queryWrapper.le("create_time", queryDTO.getCreateTimeEnd());
        }

        // 按创建时间降序排序
        // 最新发布的帖子排在前面，符合用户浏览习惯
        queryWrapper.orderByDesc("create_time");

        // 执行分页查询
        // 调用MyBatis-Plus的selectPage方法，自动分页并返回IPage对象
        IPage<AllArticle> articlePage = articleMapper.selectPage(page, queryWrapper);

        // 封装分页结果
        // 转换为自定义的PageResult对象，统一API返回格式
        PageResult<AllArticle> pageResult = new PageResult<>();
        pageResult.setPageNum(queryDTO.getPageNum());
        pageResult.setPageSize(queryDTO.getPageSize());
        pageResult.setTotal(articlePage.getTotal());
        pageResult.setPages((int) articlePage.getPages());
        pageResult.setList(articlePage.getRecords());

        return pageResult;
    }

    /**
     * 更新帖子状态（审核功能）
     * 单独提取状态更新方法，便于权限控制和日志记录扩展
     */
    @Override
    public boolean updateArticleStatus(Long id, Integer status) {
        // 创建帖子对象，仅设置需要更新的字段
        // 使用部分更新减少数据库交互数据量
        AllArticle article = new AllArticle();
        article.setId(id);
        article.setStatus(status);

        // 调用updateById方法更新状态
        // MyBatis-Plus会自动生成UPDATE语句，只更新非空字段
        return updateById(article);
    }

    // 新增统计实现
    //方法统计状态为"已发布"(status=2)的文章总数，通过QueryWrapper构建查询条件并调用count()方法实现
    @Override
    public long countPublishedArticles() {
        QueryWrapper<AllArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 2); // 状态2表示已发布
        return count(queryWrapper);
    }

    //方法计算所有已发布文章的总浏览量(view_count字段)，使用stream()流式处理对查询结果进行非空过滤和求和操作
    @Override
    public long sumTotalViewCount() {
        QueryWrapper<AllArticle> queryWrapper = new QueryWrapper<>();
        // 筛选已发布状态的文章（status=2），确保只统计有效内容
        queryWrapper.eq("status", 2);
        // 查询view_count字段值，返回的是Object类型列表（可能包含BigInteger/Long等数值类型）
        return articleMapper.selectObjs(queryWrapper.select("view_count"))
                .stream()
                // 过滤null值，避免空指针异常
                .filter(Objects::nonNull)
                // 关键修复：将Object统一转换为Number类型，再调用longValue()获取长整型
                // 原因：数据库查询返回的数值类型可能是BigInteger（尤其是聚合查询时），直接强转Long会导致类型转换异常
                .mapToLong(o -> ((Number) o).longValue())
                // 累加所有浏览量
                .sum();
    }

    //方法按日期分组统计每日发布的文章数量,获取所有已发布文章的浏览趋势，返回一个List<Map<String, Object>>，包含日期和浏览量的键值对
    @Override
    public List<Map<String, Object>> getPublishTrendByDate() {
        QueryWrapper<AllArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 2)
                .select("DATE_FORMAT(create_time, '%Y-%m-%d') as date", "COUNT(*) as count")
                .groupBy("date")
                .orderByAsc("date");
        return articleMapper.selectMaps(queryWrapper);
    }
}